package com.param_validate_demo.validator;

import com.param_validate_demo.annotation.EnumValidate;
import com.param_validate_demo.enums.MyEnum;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class EnumValidator implements ConstraintValidator<EnumValidate, Object> {

    private boolean required;
    private Class<? extends Enum<?>> enumClass;

    @Override
    public void initialize(EnumValidate constraintAnnotation) {
        this.required = constraintAnnotation.required();
        this.enumClass = constraintAnnotation.enumClass();
    }

    @Override
    public boolean isValid(Object param, ConstraintValidatorContext constraintValidatorContext) {
        // 如果不需要校验，并且参数为空则不校验，直接放行，否则如果 required = false、param不是空也要校验
        if (!required && Objects.isNull(param)) {
            return true;
        }
        if (Objects.isNull(enumClass) || Objects.isNull(param)) {
            return false;
        }
        if (MyEnum.class.isAssignableFrom(enumClass)) {
            MyEnum[] myEnums = (MyEnum[]) enumClass.getEnumConstants();
            if (Objects.isNull(myEnums)) {
                return false;
            }
            List<String> codes = Arrays.stream(myEnums).map((MyEnum::getCode)).collect(Collectors.toList());
            if (param instanceof Collection) {
                Collection<?> collection = ((Collection<?>) param);
                return collection.stream().allMatch((Object o) -> codes.contains(o.toString()));
            } else if (param.getClass().isArray()) {
                return Arrays.stream((Object[]) param).allMatch((Object o) -> codes.contains(o.toString()));
            } else {
                // 单个参数
                return codes.stream().anyMatch((String item) -> Objects.equals(item, param));
            }
        }
        return false;
    }
}
